/*
* Copyright (c) 2016 . All Rights Reserved.
*/
package com.cgmnx.admin.biz.rbac.impl;

import com.cgmnx.admin.biz.rbac.ResourceBiz;
import com.cgmnx.admin.common.bean.Limiter;
import com.cgmnx.admin.common.bean.Template;
import com.cgmnx.admin.common.enums.ValidEnumType;
import com.cgmnx.admin.common.exception.BizException;
import com.cgmnx.admin.common.exception.Preconditions;
import com.cgmnx.admin.dao.entity.rbac.ResourceEntity;
import com.cgmnx.admin.dao.entity.rbac.ResourceTree;
import com.cgmnx.admin.model.enums.rbac.OperationType;
import com.cgmnx.admin.service.aop.Loggable;
import com.cgmnx.admin.service.rbac.ResourceService;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author: created  Date: 16/12/14 Time: 下午4:05
 * @version: 1.0
 */
@Slf4j
@Service
public class ResourceBizImpl implements ResourceBiz {

    @Autowired
    private ResourceService resourceService;

    @Override
    @Transactional
    @Loggable(description = "保存权限信息", type = OperationType.URL)
    public Integer save(final ResourceEntity resourceEntity) {
        return new Template<Integer>() {
            @Override
            protected void check() {
                Preconditions.checkNotNull(resourceEntity, "资源信息不能为空");
            }

            @Override
            protected Integer exec() throws Exception {

                ResourceEntity entity = resourceService.query(resourceEntity.getId());

                if (entity != null) {
                    throw new BizException("节点已经存在");
                }


                //查询父节点
                if (resourceEntity.getParentId() > 0) {
                    ResourceEntity parent = resourceService.query(resourceEntity.getParentId());
                    //跟新treeCode
                    resourceEntity.setTreeCode(parent.getTreeCode());
                    resourceEntity.setParentName(parent.getName());
                    //更新父节点的nodeCount
                    resourceService.updateNodeCountIncr(parent.getId());


                }
                //保存子节点
                resourceService.save(resourceEntity);

                //更新子节点的treecode
                resourceEntity.setTreeCode(resourceEntity.getTreeCode() + resourceEntity.getId() + "#");
                resourceService.update(resourceEntity);

                return resourceEntity.getId();
            }
        }.execute();

    }

    @Override
    @Transactional
    @Loggable(description = "删除权限信息", type = OperationType.URL)
    public Void delete(final Integer resourceId) {
        return new Template<Void>("ResourceBizImpl_delete") {

            @Override
            protected void check() {
                Preconditions.checkArgument(resourceId > 1, " 节点ID应该大于1.");
            }

            @Override
            protected Void exec() throws Exception {
                ResourceEntity entity = resourceService.query(resourceId);

                Preconditions.checkNotNull(entity, "节点已经存在");
                List<ResourceEntity> resourceEntities = resourceService.queryChildren(entity.getParentId());
                Preconditions.checkArgument(CollectionUtils.isNotEmpty(resourceEntities), "存在子节点不能为空");

                //更新父节点的nodeCount
                ResourceEntity parentNode = resourceService.query(entity.getParentId());
                resourceService.updateNodeCountDecr(parentNode.getId());
                //删除子节点
                resourceService.updateStatus(Lists.newArrayList(resourceId), ValidEnumType.INVALID);

                return null;
            }
        }.execute();
    }

    @Override
    @Loggable(description = "更新权限信息", type = OperationType.URL)
    public Integer update(final ResourceEntity roleEntity) {
        return new Template<Integer>() {
            @Override
            protected void check() {
                Preconditions.checkNotNull(roleEntity, "资源信息不能为空");
            }

            @Override
            protected Integer exec() throws Exception {

                ResourceEntity query = resourceService.query(roleEntity.getParentId());
                Preconditions.checkNotNull(roleEntity, "父资源信息不能为空");

                roleEntity.setParentName(query.getParentName());

                return resourceService.update(roleEntity);
            }
        }.execute();
    }

    @Override
    @Loggable(description = "更新权限为无效状态", type = OperationType.URL)
    public Void updateInValidStatus(final List<Integer> idList) {
        return new Template<Void>() {
            @Override
            protected void check() {
                Preconditions.checkArgument(CollectionUtils.isNotEmpty(idList), "资源列表不能为空");
            }

            @Override
            protected Void exec() throws Exception {
                resourceService.updateStatus(idList, ValidEnumType.INVALID);
                return null;
            }
        }.execute();
    }

    @Override
    @Loggable(description = "更新权限为有效状态", type = OperationType.URL)
    public Void updateValidStatus(final List<Integer> idList) {
        return new Template<Void>() {
            @Override
            protected void check() {
                Preconditions.checkArgument(CollectionUtils.isEmpty(idList), "资源列表不能为空");
            }

            @Override
            protected Void exec() throws Exception {
                resourceService.updateStatus(idList, ValidEnumType.VALID);
                return null;
            }
        }.execute();
    }


    @Override
    public Integer count(final String searchName) {
        return new Template<Integer>() {
            @Override
            protected void check() {
            }

            @Override
            protected Integer exec() throws Exception {
                return resourceService.count(searchName);
            }
        }.execute();
    }

    @Override
    public List<ResourceEntity> queryPage(final String searchName, final Limiter limiter) {
        return new Template<List<ResourceEntity>>() {
            @Override
            protected void check() {
                Preconditions.checkNotNull(limiter, "分页信息不能为空");
            }

            @Override
            protected List<ResourceEntity> exec() throws Exception {
                return resourceService.queryPage(searchName, limiter);
            }
        }.execute();
    }

    @Override
    public ResourceEntity query(final Integer resourceId) {
        return new Template<ResourceEntity>() {
            @Override
            protected void check() {
                Preconditions.checkNotNull(resourceId, "资源Id不能为空");
            }

            @Override
            protected ResourceEntity exec() throws Exception {
                return resourceService.query(resourceId);
            }
        }.execute();
    }

    @Override
    public List<ResourceEntity> queryByUserId(final String userId) {
        return new Template<List<ResourceEntity>>() {
            @Override
            protected void check() {
                Preconditions.checkArgument(StringUtils.isNotBlank(userId), "用户Id不能为空");
            }

            @Override
            protected List<ResourceEntity> exec() throws Exception {
                return resourceService.queryByUserId(userId);
            }
        }.execute();
    }

    @Override
    public List<ResourceEntity> queryByRoleId(final Integer roleId) {
        return new Template<List<ResourceEntity>>() {
            @Override
            protected void check() {
                Preconditions.checkNotNull(roleId, "角色Id不能为空");
            }

            @Override
            protected List<ResourceEntity> exec() throws Exception {
                return resourceService.queryByRoleId(roleId);
            }
        }.execute();
    }

    @Override
    public List<ResourceTree> queryTree(final Integer uriId) {
        return new Template<List<ResourceTree>>() {
            @Override
            protected void check() {
                Preconditions.checkNotNull(uriId, "角色Id不能为空");
            }

            @Override
            protected List<ResourceTree> exec() throws Exception {
                return resourceService.queryTree(uriId);
            }
        }.execute();
    }

    @Override
    public List<ResourceEntity> queryAll() {
        return new Template<List<ResourceEntity>>() {
            @Override
            protected void check() {

            }

            @Override
            protected List<ResourceEntity> exec() throws Exception {
                return resourceService.queryAll();
            }
        }.execute();
    }


}